package server

import (
	"context"
	"core/corestruct"
	"core/datetime"
	"core/id"
	mymongo "core/mongo"
	"core/server/baseserver"
	"fmt"
	"iotall/iotcore/entity"
	"time"

	"github.com/dubbogo/gost/log/logger"
	"go.mongodb.org/mongo-driver/bson"
	"go.mongodb.org/mongo-driver/mongo"
	"go.mongodb.org/mongo-driver/mongo/options"
)

type DeviceServer struct {
	baseserver.BaseServer
	list  *corestruct.QueueT[entity.StdPkgDeviceMongo]
	today string
}

func (p *DeviceServer) Start() {
	p.BaseServer.Name = "设备值"
	p.BaseServer.Interval = 5000
	p.BaseServer.DoInterval = p.DoInterval
	p.BaseServer.DoClose = p.DoInterval

	p.list = &corestruct.QueueT[entity.StdPkgDeviceMongo]{}
	p.BaseServer.Start()
}
func (p *DeviceServer) DoInterval() {
	p.Save()
	if time.Now().Minute() == 59 && time.Now().Second() >= 55 {
		for time.Now().Second() >= 55 {
			time.Sleep(time.Millisecond * 100)
		}
		p.Save()
	}

}

func (p *DeviceServer) GetDId(sid, did string) string {
	return fmt.Sprintf("%v*%v", sid, did)
}
func (p *DeviceServer) GetPId(sid, did, pid string) string {
	return fmt.Sprintf("%v*%v*%v", sid, did, pid)
}
func (p *DeviceServer) Save() {
	var maxbatch = 2000
	var list = p.list.PopAll(maxbatch)
	if len(list) == 0 {
		return
	}

	var today = datetime.FormatDate(time.Now())
	var colname = "StdPkgPropValue" + p.today
	if today != p.today {
		p.today = today
		colname = "StdPkgPropValue" + p.today
		mymongo.Db.CreateCollection(context.Background(), colname)
		var im = mongo.IndexModel{
			Keys:    bson.D{{"fullId", 1}},
			Options: options.Index().SetUnique(false),
		}
		var col = mymongo.Db.Collection(colname)
		col.Indexes().CreateOne(context.Background(), im)
	}

	//var operationsdev []mongo.WriteModel
	var his []mongo.WriteModel

	for _, mdev := range list {

		// filter := bson.M{"_id": mdev.Id}
		// var updatefields = bson.M{
		// 	"crtDt":      datetime.NowStr(),
		// 	"propValues": mdev.PropValues,
		// }
		// update := bson.M{"$set": updatefields}
		// operation := mongo.NewUpdateOneModel()
		// operation.SetFilter(filter)
		// operation.SetUpdate(update)
		// operation.SetUpsert(false) // 如果存在数据执行更新，否则插入
		// operationsdev = append(operationsdev, operation)

		for _, vpv := range mdev.PropValues {
			var mpv = &entity.StdPkgPropValueHis{
				Id: id.NewId(),
				// Sid:    mdev.Sid,
				// Did:    mdev.Did,
				// Pid:    vpv.Id,
				FullId: p.GetPId(mdev.Sid, mdev.Did, vpv.Id),

				Fv:    vpv.Fv,
				Sv:    vpv.Sv,
				State: vpv.State,
				CrtDt: datetime.NowStr(),
			}
			operationadd := mongo.NewInsertOneModel()
			operationadd.SetDocument(mpv)
			his = append(his, operationadd)
		}

	}
	// collection := mymongo.Db.Collection("StdPkgDevice")
	// r, err := collection.BulkWrite(context.Background(), operationsdev)
	// if err != nil {
	// 	logger.Error(err)
	// } else {
	// 	logger.Infof("StdPkgDevice InsertedCount:%v  ModifiedCount:%v UpsertedCount:%v\r\n", r.InsertedCount, r.ModifiedCount, r.UpsertedCount)
	// }

	collection := mymongo.Db.Collection(colname)
	r, err := collection.BulkWrite(context.TODO(), his)
	if err != nil {
		logger.Error(err)
	} else {
		logger.Infof("StdPkgPropValue InsertedCount:%v  ModifiedCount:%v UpsertedCount:%v\r\n", r.InsertedCount, r.ModifiedCount, r.UpsertedCount)
	}
	if maxbatch == len(list) {
		p.Save()
	}
}

func (p *DeviceServer) Push(m entity.StdPkgDeviceMongo) {
	p.list.Push(m)
}

var DeviceSvr *DeviceServer

func init() {
	DeviceSvr = &DeviceServer{}
	DeviceSvr.Start()
}
